Kurt Hsu's blog

The Rails developer in taiwan.


  • 首頁

  • 標籤

  • 分類

  • 歸檔

[JavaScript] by value V.S by reference的行為

發表於 2017-04-26 更新於 2019-08-20 分類於 JavaScript

在JS的其中一個重要觀念是當創造一個變數var a;他會佔據一個記憶體位置,而當賦予給他值的時候a = 1;會把a的記憶體位置拷貝並且指向這個純質(1)。

這觀念或許很抽象,白話來講創造變數的時候他會是一個空白的記憶體,當你賦予它值var a = 1;的時候他會去拷貝1這個純質。

那什麼是by value和by reference呢?我們先來看最簡單的by value。

by value

只要給變數純質(primitive),例如數值、字串、布林值等非物件的東西會產生by value這個動作。

我們直接看看例子:

1
2
3
4
5
var a = 1;
var b = a;
a = 2;
console.log(a); //print 2
console.log(b); //print 1

答案非常的直覺,但底下發生了什麼事情?

首先我們的程式碼會先產生Hoisting(創造與提升)這個動作,讓a和b各自有一個記憶體空間,賦予a等於純質1,記憶體拷貝並指向了這個純質。

再來b = a;的時候因為a的記憶體剛剛拷貝和指向了一個純質,所以b的記憶體也拷貝並指向了相同的純質,這時候!!雖然a和b的記憶體指向完全一模一樣的純質,但由於by value的行為其實a和b的記憶體位置是不一樣的!!!

白話譬喻的話就是a買了一棟信義區的房子,此時b說要買跟a一樣的房子,所以他們都有一模一樣在信義區的房子,但是地址是不一樣的,這就是by value的行為,非常好懂,再來我們看看by reference。

by reference

只要給物件(function算是物件)的東西會產生by reference這個動作。

再來直接參考下面的例子:

1
2
3
4
5
var a = { greeting: 'Hi'};
var b = a;
a.greeting = 'Bye';
console.log(a); //print Object { greeting: "Bye" }
console.log(b); //print Object { greeting: "Bye" }

直接看結果我們發現b竟然跟a直接同化了!!發生了什麼事情?

比照剛剛by value的行為即使讓b直接等於a取得一模一樣的純質,但是b的記憶體位置是一個新的位置!

相反的by reference的行為並不會給b一個新的記憶體位置,所以直接變動a或者是b物件裡面的東西它們都會一起受影響,因為他們就是住在同一個屋簷底下。

想同的規則即使是在function裡面的參數(parameter)也是一樣

直接看例子:

1
2
3
4
5
6
7
8
9
10
11
var a = { greeting: 'Hi'};
var b = a;
a.greeting = 'Bye';
console.log(a); //print Object { greeting: "Bye" }
console.log(b); //print Object { greeting: "Bye" }
function changeName (obj) {
obj.greeting = 'morning';
}
changeName(b);
console.log(a); //print Object { greeting: "morning" }
console.log(b); //print Object { greeting: "morning" }

傳入changeName的參數會改動參數裡greeting的值變為morning,由於by reference的行為a也被我同步了!

如果是用物件實體(object literal)的方式指定物件的值,那麼會是by value

直接看例子:

1
2
3
4
5
var a = { greeting: 'Hi'};
var b = a;
b = { greeting:'Bye' };
console.log(a); //print Object { greeting: "Hi" }
console.log(b); //print Object { greeting: "Bye" }

結果不會同步!!

因為b = { greeting:'Bye' };這行等同於b自己創造了一了新的物件,所以b和a已經不是共用同一個記憶體位置了,簡單的說b已經不和a住在同一個屋簷下,b自己買了新房子了!

如果是用b.greeting = 'Bye';這種方法是更改物件裡面的內容,也就是還在同一個屋簷下但是做了裝潢,當然兩個同居的人就會享有一樣的效果,這就是by value和by reference的行為。

了解了這個在規劃的時候要盡量避免踩上這些地雷,所以在操縱變數的時候要注意一下這些觀念,不然這算是非常難degug的東西,尤其在angular的$scope運用會死得很慘XD。

# JavaScript # by value # by reference
「直播」與Boostrap做朋友-Nic老師
「直播」xdite教你克服情緒 & Nic 教你克服 DB
  • 文章目錄
  • 本站概要

Kurt Hsu

Progress One Percent Every Day
171 文章
55 分類
163 標籤
RSS
  1. 1. by value
  2. 2. by reference
    1. 2.0.1. 想同的規則即使是在function裡面的參數(parameter)也是一樣
  • 3. 如果是用物件實體(object literal)的方式指定物件的值,那麼會是by value
  • © 2020 Kurt Hsu
    由 Hexo 強力驅動 v3.8.0
    |
    主題 – NexT.Muse v7.3.0